home *** CD-ROM | disk | FTP | other *** search
- Path: linus.mitre.org!spectre!eachus
- From: eachus@spectre.mitre.org (Robert I. Eachus)
- Newsgroups: comp.lang.ada,comp.lang.c++
- Subject: Re: on OO differnces between Ada95 and C++
- Date: 20 Feb 1996 19:15:14 GMT
- Organization: The Mitre Corp., Bedford, MA.
- Message-ID: <EACHUS.96Feb20141514@spectre.mitre.org>
- References: <4gbq7q$g08@qualcomm.com>
- NNTP-Posting-Host: spectre.mitre.org
- In-reply-to: nabbasi@qualcomm.com's message of 20 Feb 1996 06:37:46 GMT
-
- In article <4gbq7q$g08@qualcomm.com> nabbasi@qualcomm.com (Nasser Abbasi) writes:
-
- > I have been playing around with the OO features in Ada95 and
- > comparing it with C++. I noticed this little difference, and I'd
- > like to see what you think of it...
-
- > In C++, the client to the saving_account class can also use the
- > Money_Type type (even though that is defined in the base class
- > Account) without having to include base class "account.h", this is
- > because Money_Type has become a public part of the Saving_Account
- > class when Saving_Account inherited Saving class.
-
- Not quite true. The visibility is because the copy semantics
- associated with #include are transitive. Anyone who includes
- saving_account also copies account, and in fact the "standard" C
- idiom of defining a global and testing it around #includes is to avoid
- including multiple copies.
-
- > In Ada95, the client of Saving_Account has no viability to Money_Type
- > type definition even though they with'ed Saving_account package, since
- > Money_Type is not a "inherited" by the Saving_Account package
- > from the Account package.
-
- Again it is a little more complex than that. In Ada 95 the type is
- in scope throughout all of the semantic dependents, but the name of
- the type or of its operations is visible in a subset of that range.
- In any case there are several different ways of making visible (or
- directly visible) the name and operations of Money_Type.
-
- > This means that in Ada95, If one wants to access things like type
- > definitions that are not tagged, but used in defining components
- > inside the tagged record, one must "with" the client package and
- > also packages that the client package with'ed just to be able to
- > have viability to those type definitions.
-
- No, another solution is to re-export them from Saving_Account.
- That is seldom the right solution in Ada, and is probably not right
- here.
-
- > In this case, It seems the C++ way of having everything inside the
- > public base class becoming visible to clients of the derived class
- > that inherits the base class is more economical?.
-
- > ...Any better way?
-
- Yes, 1) restructure your program to use child packages:
-
- ----------------- accounting.ads
-
- package Accounting is
-
- type Money_Type is delta 0.01 digits 9; -- just my example ;-)
- type Account_Id is private;
-
- private
-
- type Account_Id is new Integer;
-
- end Accounting;
-
- ------------------ account.ads ---------------------------
-
- package Accounting.Account is
-
- type Account_Type is tagged private;
-
- -- operations on type Account_Type defined here including
-
- procedure Set_Balance(A: Account, M: Accounting.Money_Type);
-
- private
-
- function New_Account_ID return Account_ID;
-
- type Account_Type is tagged
- record
- Balance : Money_Type := 0.0;
- Id : Account_Id := New_Account_ID;
- end record;
-
- end Account;
-
- ----------------- saving_account.ads ----------------
-
- with Accounting.Account;
- package Saving_Account is
-
- type Saving_Account_Type is new Account.Account_Type with private;
-
- -- new operations on savings accounts defined here including
-
- private
-
- type Saving_Account_Type is new Account.Account_Type with
- record
- Interest : Account.Money_Type;
- end record;
-
- end Saving_Account;
-
- --------------- main.adb ---------------------------
-
- with Accounting.Saving_Account;
- -- with of Accounting is implicit, with of Accounting.Acount unneeded.
- with Ada.Text_IO; use Ada.Text_IO;
-
- procedure main is
- package Money_IO is new Ada.Text_IO.Decimal_IO(Accounting.Money_Type);
- The_Saving_Account : Saving_Account.Saving_Account_Type;
- The_Balance : Accounting.Money_Type;
- begin
- Money_IO.Get(The_Balance);
- Set_Balance(The_Saving_Account, The_Balance);
- end Main;
-
- I added the use of private parts to emphasize the way this works.
- The operations declared explicitly or implicitly within the private
- part of Accounting are visible within the children of Accounting as
- well. So I could, if I wanted, hide the full declaration of
- Money_Type, and the instantiation of Money_IO within the private part
- of Accounting, and explicitly export operations which do IO from
- Accounting.Account. Of course this would implicitly define the same
- operations for Saving_Account and/or I could add additional IO
- operations.
-
- All in all a bit heavy for such a small example. But in larger
- programs, you find yourself pushing for information hiding wherever
- possible.
-
- --
-
- Robert I. Eachus
-
- with Standard_Disclaimer;
- use Standard_Disclaimer;
- function Message (Text: in Clever_Ideas) return Better_Ideas is...
-